package com.ape.mapsa.common;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import com.ape.mapsa.produccion.model.Muestra;
import com.ape.mapsa.produccion.service.IProduccionService;

@ManagedBean(name = "muestrasMB")
@SessionScoped
public class MuestrasBean implements Serializable {

	private static final long serialVersionUID = 5591853302070050847L;

	private static final Logger log = Logger.getLogger(MuestrasBean.class);

	@ManagedProperty(value = "#{produccionService}")
	private IProduccionService prodService;

	private List<Muestra> muestras;
	private List<Muestra> muestrasFiltrados = new ArrayList<Muestra>();
	private Muestra selectedMuestra = null;
	private boolean rowSelected = false;

	private StreamedContent image;

	private Muestra result;

	private Muestra newMuestra;

	private UploadedFile uploadedFile;

	@PostConstruct
	public void initialize() {
		log.info("Initializing MUESTRAS BEAN");
		muestras = new ArrayList<Muestra>();
		newMuestra = new Muestra();
		setMuestras(prodService.getAllMuestras());
		muestrasFiltrados.addAll(muestras);
	}

	public void addMuestra() {
		FacesContext context = FacesContext.getCurrentInstance();
		RequestContext requestContext = RequestContext.getCurrentInstance();
		log.info("Upload file");
		for (Muestra muestra : muestras) {
			if (newMuestra.getName().equals(muestra.getName())) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Nombre de muestra duplicado");
				context.addMessage(null, msg);
				requestContext.addCallbackParam("isValid", false);
				break;
			}
		}
		if (uploadedFile == null) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Archivo erroneo");
			context.addMessage("addMuestraForm:addMessages", msg);
			requestContext.addCallbackParam("isValid", false);
		} else {
			if (!uploadedFile.getFileName().endsWith("jpg") && !uploadedFile.getFileName().endsWith("png")
					&& !uploadedFile.getFileName().endsWith("gif")) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Extension: ", "Debe ser una de [jpg, png, gif] "
						+ uploadedFile.getFileName());
				context.addMessage(null, msg);
				requestContext.addCallbackParam("isValid", false);
			}
			if (uploadedFile.getSize() > 8000000) {
				FacesMessage msgx = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Tamaño:", "EL tamaño del archivo " + uploadedFile.getFileName()
						+ " ( " + String.valueOf(uploadedFile.getSize() / 1000000f) + " MB ) " + "debe ser menor a 7.62 MB");
				context.addMessage(null, msgx);
				requestContext.addCallbackParam("isValid", false);
			}
		}

		if (requestContext.getCallbackParams().get("isValid") == null || !((Boolean) requestContext.getCallbackParams().get("isValid"))) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Archivo cargado", uploadedFile.getFileName());
			context.addMessage(null, msg);

			byte[] bFile = new byte[(int) uploadedFile.getSize()];

			try {
				InputStream fileInputStream = uploadedFile.getInputstream();
				// convert file into array of bytes
				fileInputStream.read(bFile);
				fileInputStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

			newMuestra.setContent(bFile);
			newMuestra.setCreated(new Date());
			newMuestra.setFileName(uploadedFile.getFileName());
			newMuestra.setContentType("Imagen");
			try {
				prodService.saveMuestra(newMuestra);
				muestras.add(newMuestra);
				muestrasFiltrados.add(newMuestra);
			} catch (Exception x) {
				log.error(x);
				FacesMessage msgx = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error ",
						"Que verguenza, La muestra no pudo ser agregada, por favor comuniquese con el gerente de sistemas");
				context.addMessage(null, msgx);
				requestContext.addCallbackParam("isValid", false);
			}
		}
	}

	public StreamedContent getDynaImage() {
		FacesContext fc = FacesContext.getCurrentInstance();
		Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
		String fileName = params.get("fileName");
		StreamedContent image = new DefaultStreamedContent();
		for (Muestra muestra : muestras) {
			if (muestra.getFileName().equals(fileName)) {
				image = new DefaultStreamedContent(new ByteArrayInputStream(muestra.getContent()), "image/jpg");
				break;
			}
		}
		return image;
	}

	public void rowSelected(SelectEvent event) {
		log.info("muestra row selected");
		setRowSelected(selectedMuestra != null);
		result = selectedMuestra;
	}

	public void getMuestra(ActionEvent actionEvent) {
		result = selectedMuestra;
	}

	public IProduccionService getProdService() {
		return prodService;
	}

	public void setProdService(IProduccionService prodService) {
		this.prodService = prodService;
	}

	public Muestra getNewMuestra() {
		return newMuestra;
	}

	public void setNewMuestra(Muestra newMuestra) {
		this.newMuestra = newMuestra;
	}

	public List<Muestra> getMuestras() {
		return muestras;
	}

	public void setMuestras(List<Muestra> muestras) {
		this.muestras = muestras;
	}

	@PreDestroy
	public void predestroy() {
		log.info("MUESTRAS BEAN BEAN IS GOING TO BE DESTROYED");
	}

	public Muestra getSelectedMuestra() {
		return selectedMuestra;
	}

	public void setSelectedMuestra(Muestra selectedMuestra) {
		this.selectedMuestra = selectedMuestra;
	}

	public List<Muestra> getMuestrasFiltrados() {
		return muestrasFiltrados;
	}

	public void setMuestrasFiltrados(List<Muestra> muestrasFiltrados) {
		this.muestrasFiltrados = muestrasFiltrados;
	}

	public boolean isRowSelected() {
		return rowSelected;
	}

	public void setRowSelected(boolean rowSelected) {
		this.rowSelected = rowSelected;
	}

	public Muestra getResult() {
		return result;
	}

	public void setResult(Muestra result) {
		this.result = result;
	}

	public UploadedFile getUploadedFile() {
		return uploadedFile;
	}

	public void setUploadedFile(UploadedFile uploadedFile) {
		this.uploadedFile = uploadedFile;
	}

	public StreamedContent getImage() {
		if (image != null) {
		} else {
			return new DefaultStreamedContent(new ByteArrayInputStream(new byte[] {}), "");
		}
		return image;
	}

	public void setImage(StreamedContent image) {
		this.image = image;
	}

}
